﻿// -----------------------------------------------------------------------
// <copyright file="NotificationService.cs" company="EPAM Systems">
////Copyright (c) EPAM Systems, 2012. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

namespace MBOP.Notification.Services
{
	#region Usings

	using System;
	using System.Collections.Generic;
	using System.Text;
	using System.Web;

	using MBOP.Configuration.ConfigElements;
	using MBOP.Core.Entities.Common;
	using MBOP.Core.Entities.Notification;
	using MBOP.Core.Interfaces.Notification;
	using MBOP.Notification.Common;

	#endregion

	/// <summary>
	/// Provides the common functionality for notification
	/// </summary>
	public class NotificationService : INotificationService
	{
		#region Constants

		/// <summary>
		/// Represents the dot separator.
		/// </summary>
		private const string SEPARATOR_DOT = ".";

		/// <summary>
		/// Represents the template file format.
		/// </summary>
		private const string FILE_FORMAT_TEMPLATE = ".xml";

		#endregion

		#region Private Fields

		/// <summary>
		/// Represents the notification engines.
		/// </summary>
		private IEnumerable<INotificationEngine> _notificationEngines;

		/// <summary>
		/// Represents the notification service configuration.
		/// </summary>
		private NotificationServicesElement _configElement;

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="NotificationService"/> class.
		/// </summary>
		/// <param name="notificationEngines">The collection of the notification engines.</param>
		/// <param name="configElement">The notification service configuration element.</param>
		public NotificationService(IEnumerable<INotificationEngine> notificationEngines, NotificationServicesElement configElement)
		{
			this._notificationEngines = notificationEngines;
			this._configElement = configElement;
		}

		#endregion

		#region INotificationService Implementation

		#region Methods

		/// <summary>
		/// Handles the notification event.
		/// </summary>
		/// <param name="notification">The type of the notification.</param>
		/// <param name="receiversIdentityCollection">Collection of the receivers identities.</param>
		/// <param name="eventData">The data of the event</param>
		public void HandleEvent(Enum notification, IDictionary<string, PersonFindingType> receiversIdentityCollection, dynamic eventData)
		{
			string notificationFilePath = this.GetTemplateFilePath(notification);

			IEnumerable<NotificationTemplate> templates = NotificationTemplateParcer.Parse(notificationFilePath);

			foreach (var template in templates)
			{
				this.Notify(template, receiversIdentityCollection, eventData);
			}
		}

		#endregion

		#endregion

		#region Private Methods

		/// <summary>
		/// Gets the event template file path based on notification type.
		/// </summary>
		/// <param name="notification">The type of the notification.</param>
		/// <returns>The template file path.</returns>
		private string GetTemplateFilePath(Enum notification)
		{
			Type enumType = notification.GetType();

			Type reflectedType = enumType.ReflectedType;

			StringBuilder notificationPathBuilder = new StringBuilder(string.Empty);

			if (reflectedType != null)
			{
				notificationPathBuilder.Append(reflectedType.Name);
				notificationPathBuilder.Append(SEPARATOR_DOT);
			}

			notificationPathBuilder.Append(enumType.Name);
			notificationPathBuilder.Append(SEPARATOR_DOT);
			notificationPathBuilder.Append(notification.ToString());

			string templateFolder = string.Empty;

			if (HttpContext.Current != null)
			{
				templateFolder = HttpContext.Current.Server.MapPath(this._configElement.TemplatePath);
			}
			else
			{
				templateFolder = this._configElement.TemplatePath;
			}

			notificationPathBuilder.Insert(0, templateFolder);

			notificationPathBuilder.Append(FILE_FORMAT_TEMPLATE);

			return notificationPathBuilder.ToString();
		}

		/// <summary>
		/// Notifies the current notification engines.
		/// </summary>
		/// <param name="template">The notification template.</param>
		/// <param name="receiversIdentityCollection">Collection of the receivers identities.</param>
		/// <param name="eventData">The data of the event</param>
		private void Notify(NotificationTemplate template, IDictionary<string, PersonFindingType> receiversIdentityCollection, dynamic eventData)
		{
			foreach (var notificationEngine in this._notificationEngines)
			{
				notificationEngine.Notify(template, receiversIdentityCollection, eventData);
			}
		}

		#endregion
	}
}
